package com.xiaoying.server.publish.servlet;

import java.io.File;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javax.jms.JMSException;


import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xiaoying.server.publish.Handler;
import com.xiaoying.server.publish.entity.FileInfo;
import com.xiaoying.server.publish.entity.UploadResult;
import com.xiaoying.server.publish.impl.ExceptionHandler;
import com.xiaoying.server.publish.impl.FetchRequest;
import com.xiaoying.server.publish.utils.LoggerTest;


public class Dispatcher {
	private static String baseDir = System.getProperty("user.dir")+"\\file";
    private static Log log = LogFactory.getFactory().getInstance(Dispatcher.class);
//    private static Logger logger = LoggerFactory.getLogger(Dispatcher. class);    

    private XMLConfiguration config ;
    // 上传文件请求队列
    private BlockingQueue<FileInfo> reqQueue ;
    // 上传结果结果处理队列
    private BlockingQueue<UploadResult> resQueue ;
    
    // 上传文件处理动作
    private Handler requestHandler;
    // 上传结果处理动作
    private Handler responseHandler;
    // 异常退出处理动作
    private Handler exceptionHandler;
    
//    // 上传文件队列最大容量
//    private int maxReqCache;
//    // 上传结果队列最大容量
//    private int maxResCache;
    
    
    private Dispatcher() {
    	
    }
    
    private static class DispatcherHolder {
        static final Dispatcher UNIQUEINSTANCE = new Dispatcher();
    }
    
    public static Dispatcher getInstance() {
        return DispatcherHolder.UNIQUEINSTANCE;
    }
    
    public void init(String configFile) throws Exception {
        if (log.isDebugEnabled())
            log.debug("配置文件路径："+configFile);
        try {
            config = new XMLConfiguration();
            config.setFileName(configFile);
            config.setValidating(false);
            config.load();
        } catch (Exception e) {
            log.error("配置文件错误，认证调度器服务无法启动！",e);
            throw e;
        }
        String reqHandleString = config.getString("RequestHandler[@class]");
        String resHandleString = config.getString("ResponseHandler[@class]");
        
        int maxReqCache = config.getInt("RequestHandler[@cacheSize]",100);
        int maxResCache = config.getInt("ResponseHandler[@cacheSize]",1000);

        reqQueue = new LinkedBlockingQueue<FileInfo>(maxReqCache);
        resQueue = new LinkedBlockingQueue<UploadResult>(maxResCache);
        
        Class<?> reqClass = this.getClass().getClassLoader().loadClass(reqHandleString);
        Class<?> resClass = this.getClass().getClassLoader().loadClass(resHandleString);
        
        requestHandler = (Handler)reqClass.newInstance();
        requestHandler.init(config);
        
        responseHandler = (Handler)resClass.newInstance();
        responseHandler.init(config);
        exceptionHandler = new ExceptionHandler();
        
        ShutdownHook();
    }
    
    public void startup() throws InterruptedException {
    	log.info("文件上传服务器启动中...");
        exceptionHandler.handle(reqQueue , resQueue);
        Thread.sleep(2000L);	//wait 60min
        // 异常处理开始后10L开始主线程
		new FetchRequest(reqQueue , resQueue);
        requestHandler.handle(reqQueue, resQueue);
        responseHandler.handle(reqQueue, resQueue);
        
    }
    
    public void ShutdownHook() throws Exception {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                log.info("认证调度器即将停止，检查队列中是否还有待处理数据。");
                while (!(reqQueue.isEmpty() && resQueue.isEmpty())) {
                    try {
                        wait(1000); //等待数据处理
                    } catch (InterruptedException e) {
                       log.error(e);
                    }
                }
                log.info("队列中数据已经处理完毕，认证调度器停止。");
            }
        });
    }

//	public int getMaxReqCache() {
//		return maxReqCache;
//	}
//
//	public void setMaxReqCache(int maxReqCache) {
//		this.maxReqCache = maxReqCache;
//	}
//
//	public int getMaxResCache() {
//		return maxResCache;
//	}
//
//	public void setMaxResCache(int maxResCache) {
//		this.maxResCache = maxResCache;
//	}
    
    
}
